<!--
 * 字段
 * @作者: 陈老师儿~
 * @手机: 18560000860
 -->
<template>
    <view class="pure-field" :class="classes" :style="styles" @tap="handleClick">
        <view class="pure-field-wrapper">
            <!-- Left -->
            <view class="pure-field-left" v-if="leftIcon || $slots.label || label || isRequired">
                <!-- 必填符号 -->
                <text class="pure-field-required" v-if="isRequired">{{ requiredText || formRequiredText }}</text>

                <!-- 左侧图标 -->
                <view class="pure-field-icon pure-field-icon-left" v-if="leftIcon">
                    <pure-icon :name="leftIcon" :mode="leftIconMode"></pure-icon>
                </view>

                <!-- Label -->
                <view class="pure-field-label" v-if="$slots.label || label">
                    <slot name="label" v-if="$slots.label"></slot>
                    <text class="pure-field-label-text" v-else>{{ label }}</text>
                </view>
            </view>

            <!-- Right -->
            <view class="pure-field-right">
                <!-- Content Before -->
                <view class="pure-field-before" v-if="$slots.before">
                    <slot name="before"></slot>
                </view>

                <!-- Content -->
                <view class="pure-field-content">
                    <slot></slot>
                </view>

                <!-- Content After -->
                <view class="pure-field-after">
                    <slot name="after" v-if="$slots.after"></slot>
                </view>

                <!-- 右侧图标 -->
                <view class="pure-field-icon pure-field-icon-right" v-if="rightIcon">
                    <pure-icon :name="rightIcon" :mode="rightIconMode"></pure-icon>
                </view>
            </view>
        </view>

        <!-- Error Tips -->
        <view class="pure-field-tips" v-if="errorTips">
            <!-- 这里插入节点元素是为了对齐提示文本 -->
            <view class="pure-field-element-placeholder pure-field-element-placeholder-left" v-if="leftIcon || $slots.label || label || isRequired">
                <!-- Left -->
                <view class="pure-field-left">
                    <!-- 必填符号 -->
                    <text class="pure-field-required" :data-required-text="requiredText" v-if="isRequired">{{ requiredText || formRequiredText }}</text>

                    <!-- 左侧图标 -->
                    <view class="pure-field-icon pure-field-icon-left" v-if="leftIcon">
                        <pure-icon :name="leftIcon" :mode="leftIconMode"></pure-icon>
                    </view>

                    <!-- Label -->
                    <view class="pure-field-label" v-if="$slots.label || label">
                        <slot name="label" v-if="$slots.label"></slot>
                        <text class="pure-field-label-text" v-else>{{ label }}</text>
                    </view>
                </view>
            </view>

            <!-- Tips Content -->
            <view class="pure-field-tips-content">
                {{ errorTips }}
            </view>

            <!-- 这里插入节点元素是为了对齐提示文本 -->
            <view class="pure-field-element-placeholder pure-field-element-placeholder-right" v-if="rightIcon">
                <!-- 右侧图标 -->
                <view class="pure-field-icon pure-field-icon-right">
                    <pure-icon :name="rightIcon" :mode="rightIconMode"></pure-icon>
                </view>
            </view>
        </view>
    </view>
</template>

<script>
    import props from "./props.js";
    import { computed } from "vue";
    export default {
        options: {
            // 将自定义节点设置成虚拟的
            // 头条、飞书：因为合并后丢失事件和 'provide/inject'
            // 京东：因为合并后不能合并外层 'class'
            // 百度：因为合并后会在控制台疯狂报警告
            // #ifndef MP-TOUTIAO || MP-LARK || MP-JD || MP-BAIDU
            virtualHost: true,
            // #endif

            // 组件样式隔离
            styleIsolation: "apply-shared",

            // 允许使用多个插槽
            multipleSlots: true,
        },
        props: props,
        emits: ["onClick"],
        data() {
            return {};
        },
        inject: {
            // 表单全局必填符号文本
            formRequiredText: {
                from: "formRequiredText",
                default: "*",
            },

            // 表单全局验证规则
            formRules: {
                from: "formRules",
                default: {},
            },

            // 表单全局错误信息
            formErrors: {
                from: "formErrors",
                default: [],
            },

            // 表单全局验证时机
            formValidateTrigger: {
                from: "formValidateTrigger",
                default: "submit",
            },

            // 更新字段单独配置的规则
            updateFieldRules: {
                from: "updateFieldRules",
                default: () => {
                    return () => {};
                },
            },

            // 验证表单字段
            formValidateField: {
                from: "formValidateField",
                default: () => {
                    return () => {};
                },
            },

            // 只读整个表单
            formReadonly: {
                from: "formReadonly",
                default: false,
            },

            // 禁用整个表单
            formDisabled: {
                from: "formDisabled",
                default: false,
            },

            // 全局禁用类
            formDisabledClass: {
                from: "formDisabledClass",
                default: () => {
                    return null;
                },
            },
        },
        computed: {
            // classes
            classes() {
                const classes = [];

                // 只读模式
                if (this.readonly || this.formReadonly) classes.push("pure-field-readonly");

                // 禁用模式
                if (this.disabled || this.formDisabled) classes.push(this.disabledClass || formDisabledClass);

                return classes;
            },

            // styles
            styles() {
                const styles = [];

                // 右侧图标旋转角度
                if (this.rotate !== null && this.rotate !== undefined) styles.push(`--pure-field-right-icon-transform: rotate(${this.rotate}deg);`);

                return styles;
            },

            // 是否必填
            isRequired() {
                if (this.required === "auto") {
                    // 验证规则
                    const rules = this.formRules[this.prop];

                    // 非数组转成数组
                    const rulesArray = Array.isArray(rules) ? rules : [rules];

                    // 查找是否有 required 规则
                    const requiredRule = rulesArray.find((item) => item?.required);

                    return !!requiredRule;
                }
                return this.required;
            },

            // 表单验证后的错误提示
            errorTips() {
                // 先查找表单验证的错误
                const error = this.formErrors?.find?.((item) => item?.field === this.prop);
                if (error) return error.message;

                // 如果没查找到就显示配置的错误提示
                return this.tips;
            },
        },
        watch: {
            // 监听 rules 的变化
            rules: {
                handler(newRules) {
                    // 更新字段验证规则
                    if (newRules) this.updateFieldRules(this.prop, newRules);
                },
                deep: true,
                immediate: true,
            },
        },
        methods: {
            // 点击事件
            handleClick() {
                if (this.disabled) return;
                this.$emit("onClick");
            },

            // 输入框失去焦点
            onFieldBlur() {
                // 失去焦点时触发验证
                let filedRules = this.formRules[this.prop];
                if (!filedRules) return;
                if (!Array.isArray(filedRules)) filedRules = [filedRules];
                if (filedRules.find((item) => item.trigger === "blur")) {
                    this.formValidateField(this.prop);
                }
            },

            // 字段 change 事件
            onFieldChange() {
                // change 时触发验证
                let filedRules = this.formRules[this.prop];
                if (!filedRules) return;
                if (!Array.isArray(filedRules)) filedRules = [filedRules];
                if (filedRules.find((item) => item.trigger === "change")) {
                    this.formValidateField(this.prop);
                }
            },
        },
        provide() {
            return {
                // Field 组件的 blur 事件
                onFieldBlur: this.onFieldBlur,
                // Field 组件的 change 事件
                onFieldChange: this.onFieldChange,
            };
        },
    };
</script>

<style scoped>
    @import "./style.css";
</style>
